home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Biomorph 0.77 / Biomorph src / redraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-16  |  5.3 KB  |  243 lines  |  [TEXT/ALFA]

  1. #include <MacHeaders>
  2. #include "constants.h"
  3. #include "mathtype.h"
  4. #include "globals.h"
  5.  
  6. #define RECURSE         // define this for recursive descent method
  7.  
  8. static MathType xgap;            // distance between pixels
  9. static MathType ygap;
  10.  
  11.  
  12. static Boolean CheckCancel(void);    // has the user pressed Cmd-. ?
  13. static void DrawImage(Rect *rect);
  14. static int CalcPoint(int x, int y);
  15. #ifdef RECURSE
  16. static void DrawRecurse( int xmin, int xmax, int ymin, int ymax);
  17.  
  18. static int sDone;        // 's' is for statically declared var -- local
  19. static int count;        // counter for event checking
  20. #endif
  21.  
  22. void Redraw(void)
  23. {
  24.     ReadCoords();
  25.  
  26.     DrawImage( &gMainWindow->portRect);
  27. } // Redraw()
  28.  
  29.  
  30. static void DrawImage(Rect *rect)
  31. {
  32.     register int x;
  33.     register int y;
  34.     GrafPtr savedPort;
  35.     EventRecord theEvent;
  36.     
  37.     count = kEventCount;
  38.     xgap = (gXmax - gXmin) / (MathType)rect->right;
  39.     ygap = (gYmax - gYmin) / (MathType)rect->bottom;
  40.     
  41.     GetPort( &savedPort);   // get whichever window was last current
  42.     SetPort( &gOffGP);            // clean up the offscreen bitmap
  43.     EraseRect( &gOffGP.portRect);
  44.     PenPat(black);
  45.     PenMode(srcCopy);
  46.     SetPort( gMainWindow);        // set port to the drawing area
  47.     EraseRect( &gMainWindow->portRect);
  48.     PenPat(black);
  49.     PenMode(srcCopy);
  50.     
  51. #ifdef RECURSE
  52.  
  53.     // draw the image using divide & conquer
  54.     sDone = 0;
  55.     
  56.     DrawRecurse( 0, rect->right -1, 0, rect->bottom -1);
  57.     
  58.     SysBeep(5);        // beep twice when done
  59.     SysBeep(5);
  60.  
  61. #else
  62. // ...else do not do recursive drawing.  Do a normal
  63. // raster scan left to right, top to bottom.
  64. //
  65.     for (y=0; y< rect->bottom; y++)
  66.     {
  67.         for (x=0; x< rect->right; x++)
  68.         {
  69.             if (CalcPoint(x,y))
  70.             {
  71.                 SetPort(gMainWindow);    // plot the main window's image
  72.                 MoveTo(x, y);
  73.                 Line(0,0);                // plot the pixel
  74.     
  75.                 SetPort( &gOffGP);        // plot the offscreen bitmap's image
  76.                 MoveTo(x, y);
  77.                 Line(0,0);                // plot the pixel
  78.             }
  79.  
  80.             if ( ! (--count))  // check for a Cmd-period to abort.
  81.             {
  82.                 count = kEventCount;
  83.                 if (CheckCancel())    // did user cancel our pretty picture?
  84.                     goto end;
  85.             } // if
  86.         } // for x
  87.     } // for y
  88.     SysBeep(5);        // beep twice when done
  89.     SysBeep(5);
  90. #endif
  91.  
  92. end:
  93.     SetPort(savedPort);
  94.     return;
  95. } // DrawImage()
  96.  
  97.  
  98. static int CalcPoint(int x, int y)
  99. {
  100.     register int n;
  101.     ImagPt    z, z0, C;
  102.     Pattern thePat;
  103.     
  104.     C.r = gCreal;
  105.     C.i = gCimag;
  106.     z0.r = gXmin + xgap*x;
  107.     z0.i = gYmin + ygap*y;
  108.     z = z0;
  109.     
  110.     n=1;
  111.     do {
  112.         z0 = z;
  113.         (**gMorphProcH)( &z0, &C, &z);    // iterate this function
  114.         n++;
  115.     }
  116.     while ( (n <=10) && (dabs(z.r)<=10.0) &&
  117.             (dabs(z.i)<=10.0) && (z.mag <=100));
  118.     
  119.     if ( (dabs(z.r) < 10.0) || (dabs(z.i) < 10.0) )
  120.         return 1;    // pixel needs to be drawn
  121.     else
  122.         return 0;    // pixel is not drawn
  123.     
  124. } // CalcPoint()
  125.  
  126.  
  127. static Boolean CheckCancel()
  128. {
  129.     EventRecord theEvent;
  130.     
  131.     // handle all events pending...
  132.     
  133.     while ( WaitNextEvent( everyEvent, &theEvent, gSleepTime, NULL))
  134.         switch( theEvent.what)
  135.         {
  136.             case keyDown:
  137.                 if ((theEvent.modifiers & cmdKey) &&
  138.                     ((theEvent.message & charCodeMask) == '.'))
  139.                 {
  140.                     SysBeep(1);
  141.                     return 1;
  142.                 }
  143.                 break;
  144.             case mouseDown:
  145.                 {    WindowPtr whichWindow;
  146.                     int part;
  147.                     part = FindWindow(theEvent.where, &whichWindow);
  148.                     if (part == inMenuBar)
  149.                         (void)MenuSelect(theEvent.where);
  150.                 }
  151.                 break;
  152.         }
  153.     return 0;
  154. } // CheckCancel()
  155.  
  156.  
  157. void ZoomIn(void) // magnify by 2 == decrease range by half.
  158. {
  159.     ReadCoords();
  160.     gXmax -= (gXmax - gCenterX)/2.0;  // liposuck the boundaries
  161.     gXmin -= (gXmin - gCenterX)/2.0;
  162.     gYmax -= (gYmax - gCenterY)/2.0;
  163.     gYmin -= (gYmin - gCenterY)/2.0;
  164.     WriteCoords();
  165. } // ZoomIn()
  166.  
  167.  
  168. void ZoomOut(void) // magnify by 0.5 == increase range by 100%.
  169. {
  170.     ReadCoords();
  171.     gXmax = gCenterX + 2.0*(gXmax - gCenterX);
  172.     gXmin = gCenterX + 2.0*(gXmin - gCenterX);
  173.     gYmax = gCenterY + 2.0*(gYmax - gCenterY);
  174.     gYmin = gCenterY + 2.0*(gYmin - gCenterY);
  175.     WriteCoords();
  176. } // ZoomOut()
  177.  
  178.  
  179. #ifdef RECURSE
  180. static void DrawRecurse( int xmin, int xmax, int ymin, int ymax)
  181. {
  182.     int xmid, ymid;
  183.     
  184.     if ( sDone) return;
  185.     
  186.     xmid = xmax + xmin + 1;  xmid >>= 1;  // take the inclusive average
  187.     ymid = ymax + ymin + 1;  ymid >>= 1;  // take the inclusive average
  188.  
  189. // The returns inside each condition are so the code doesn't
  190. // have to BRA outside it all on every call to this function.
  191. // Having the return there eliminates costly jumps.
  192.  
  193.     if ( xmax == xmin)    // then don't split x
  194.     {
  195.         if (ymax == ymin)  // then single pixel -- do calculations
  196.         {
  197.             if (CalcPoint(xmin,ymin))
  198.             {
  199.                 SetPort(gMainWindow);    // plot the main window's image
  200.                 MoveTo(xmin,ymin);
  201.                 Line(0,0);                // plot the pixel
  202.     
  203.                 SetPort( &gOffGP);        // plot the offscreen bitmap's image
  204.                 MoveTo(xmin,ymin);
  205.                 Line(0,0);                // plot the pixel
  206.             }
  207.             
  208.             if ( ! --count )  // check for a Cmd-period to abort periodically.
  209.             {
  210.                 count = kEventCount;
  211.                 if (CheckCancel())    // did user cancel our pretty picture?
  212.                     sDone = 1;
  213.             } // if
  214.             return;
  215.         }
  216.         else
  217.         {
  218.             DrawRecurse( xmin, xmin, ymin, ymid-1);  // split y
  219.             DrawRecurse( xmin, xmin, ymid, ymax);
  220.             return;
  221.         }
  222.     }
  223.     else // split X
  224.     {
  225.         if (ymax == ymin) // then split along X only
  226.         {
  227.             DrawRecurse( xmin, xmid-1, ymin, ymin);
  228.             DrawRecurse( xmid, xmax, ymin, ymin);
  229.             return;
  230.         }
  231.         else    // split both X and Y
  232.         {
  233.             DrawRecurse( xmin, xmid-1, ymin, ymid-1);    // top left
  234.             DrawRecurse( xmid, xmax, ymin, ymid-1);        // top right
  235.             DrawRecurse( xmin, xmid, ymid, ymax);        // bot left
  236.             DrawRecurse( xmid, xmax, ymid, ymax);        // bot right
  237.             return;
  238.         }
  239.     }
  240. } // DrawRecurse()
  241. #endif
  242.  
  243.